package com.yc.chatroom.server;

import com.yc.chatroom.common.Constant;
import com.yc.chatroom.server.dao.UserRepositoryDao;
import com.yc.chatroom.server.pojo.ChannelInfo;
import com.yc.chatroom.server.pojo.LoginStatus;
import com.yc.chatroom.server.pojo.SessionInfo;
import com.yc.chatroom.server.pojo.po.UserPo;
import com.yc.chatroom.server.service.UserService;
import com.yc.chatroom.server.util.ChannelUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.yc.chatroom.common.dto.*;
import com.yc.chatroom.server.service.AuthService;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import javax.security.auth.message.AuthException;

@Component
public class ServerHandler extends ChannelInboundHandlerAdapter {
	
	@Autowired
	private AuthService authService;
	@Autowired
	private UserService userService;
	@Autowired
	private UserRepositoryDao userRepositoryDao;
	
	//在线channel group
//	public static ChannslGroup online_channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
	//添加一个用户-通道类型
	public static ChannelOnline channelOnline = new ChannelOnline();

	/**
	 * 连接断开后的处理
	 */
	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		channelOnline.remove(ctx);
		ctx.close();
	}

	/**
	 * 当服务器和客户建立连接
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		super.channelActive(ctx);
	}

	/**
	 * 收到客户端发来的消息
	 */
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		System.out.println("------server----channelRead----------");
		try {
			if(msg instanceof LoginDto) {
				handleLogin(ctx, msg);

			} else if (msg instanceof SendMsgDto) {
				System.out.println("----------MsgDto----------");
				ResultDto checkResult = channelOnline.check(ctx);
				if (Integer.valueOf(Constant.RESULT_CODE_SUCCESS).equals(checkResult.getCode())) {
					//校验通过： 接收消息，分发消息
					String msgContent = ((SendMsgDto) msg).getMessage();
					if (null != msgContent) {
						//查询用户名，封装要发的消息
						SessionInfo sessionInfo = channelOnline.getSessionInfo(ctx);
						if (null != sessionInfo) {
							ShowMsgDto showMsgDto = new ShowMsgDto(sessionInfo.getUserId(),
									sessionInfo.getUserName(), msgContent, new Date().getTime());
							showMsgDto.setMe(false);
							channelOnline.sendShowMsgForAll(showMsgDto);//分发消息
						} else {
							channelOnline.sendMsg(ctx, "服务器内部错误");
						}
					} else {
						channelOnline.sendMsg(ctx, "消息不能为空");
					}
				} else {
					//校验失败：
					if (Integer.valueOf(Constant.RESULT_CODE_SESSION_EXPIRED).equals(checkResult.getCode())) {
						channelOnline.sendMsg(ctx, "未登陆");
					} else if (Integer.valueOf(Constant.RESULT_CODE_ILLEGAL_PARAM).equals(checkResult.getCode())) {
						ctx.close();
					}

				}

			} else {
				//不可识别的消息：直接关闭
				ctx.close();

			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		

	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		ctx.close();
	}
	
	@Transactional(rollbackFor = Exception.class)
	public void handleLogin(ChannelHandlerContext ctx, Object msg) throws AuthException {
		System.out.println("----------LoginDto----------");
		ResultDto authResult = authService.checkLogin((LoginDto) msg);

		if (Integer.valueOf(Constant.RESULT_CODE_SUCCESS).equals(authResult.getCode())) {
			UserPo loginUser = (UserPo) authResult.getData();//获取登陆的用户
			//成功：更新数据库，更新登陆时间; 把channel放入集合
			channelOnline.loginSuccess(loginUser, ctx);
			userService.updateLogStatus(loginUser, LoginStatus.LOGIN);
			//通知大家这个人上线了
			SysMsgDto sysMsgDto = new SysMsgDto("用户【" + loginUser.getUserName() + "]上线了", new Date().getTime());
			channelOnline.sendCommonMsgForAll(sysMsgDto);
			//返回信息
			ctx.writeAndFlush(new LoginResponse(Constant.RESULT_CODE_SUCCESS, authResult.getMsg()));
		} else {
			//失败: 插入一个连接，空用户信息(如果长时间没有变动，该连接会被清除)
			channelOnline.loginFall(ctx);
		}
	}

//	@Override
//	protected void channelRead0(ChannelHandlerContext ctx, BaseDto msg) throws Exception {
//		System.out.println("----------channelRead0----------");
//		MsgDto msgContent = (MsgDto) msg;
//		String body = msgContent.getMessage();
//		
//		
//		System.out.println(Thread.currentThread().getName() + " - Server receive the body: " + body);
//		
//		//确定发消息的客户端身份
//		
//		Channel newChannel = ctx.channel();
//		
//		//判断newChannel是否已经在线
//		boolean online = false;
//		for (Channel channel : online_channels) {
//			if (channel.equals(newChannel)) {
//				online = true;
//				break;
//			}
//		}
//		
//		//如果是新上线
//		if (!online) {
//			//通知其他所有的客户端
//			for (Channel channel : online_channels) {
//				if (!channel.equals(newChannel)) {
//					channel.writeAndFlush("用户：[" + newChannel.remoteAddress() + "]上线了");
//				}
//			}
//			
//			//把channel加到在线channelgroup中
//			online_channels.add(newChannel);
//		} else {
//			//已上线，转发消息
//			for (Channel channel : online_channels) {
//				if (!channel.equals(newChannel)) {
//					channel.writeAndFlush("[" + newChannel.remoteAddress() + "]:" + body);
//				} else {
//					channel.writeAndFlush("[我]:" + body);
//				}
//			}
//			
//			
//		}
//		
//	}

}
